<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/11/13
 * Time: 15:38
 */

namespace console\controllers;

use common\business\CommonHelper;
use common\business\task\TaskResponseData;
use common\business\task\TaskService;
use common\consts\Consts;
use common\helpers\DateHelper;
use common\helpers\StringUtil;
use Yii;
use common\business\task\TaskHelper;
use common\models\Task;
use yii\console\Controller;
use yii\db\Exception;

class TaskController extends Controller
{
    public function actionExecuteAll(){
//        $this->actionProcessOne("0,1");
        $this->processOneCore();
    }

    /**
     * 处理后台任务,仅用于测试,正式环境不能使用.
     */
    public function actionProcessAll()
    {
        $this->actionProcessOne("0,1");
        $this->actionProcessTwo("0,1");
        $this->actionProcessThree("0,1");
        $this->actionProcessFour("0,1");
        $this->actionProcessFive("0,1");
        $this->actionProcessSix("0,1");
        $this->actionProcessSeven("0,1");
        $this->actionProcessOneHourBefore();
    }
    /**
     * 处理异步后台任务1
     *
     * @param $idSuffix
     */
    public function actionProcessOne($idSuffix)
    {
        $this->processCore($idSuffix, Consts::TASK_PRIORITY_1);
    }
    /**
     * 处理异步后台任务2
     *
     * @param $idSuffix
     */
    public function actionProcessTwo($idSuffix)
    {
        $this->processCore($idSuffix, Consts::TASK_PRIORITY_2);
    }
    /**
     * 处理异步后台任务3
     *
     * @param $idSuffix
     */
    public function actionProcessThree($idSuffix)
    {
        $this->processCore($idSuffix, Consts::TASK_PRIORITY_3);
    }
    /**
     * 处理异步后台任务4
     *
     * @param $idSuffix
     */
    public function actionProcessFour($idSuffix)
    {
        $this->processCore($idSuffix, Consts::TASK_PRIORITY_4);
    }
    /**
     * 处理异步后台任务5
     *
     * @param $idSuffix
     */
    public function actionProcessFive($idSuffix)
    {
        $this->processCore($idSuffix, Consts::TASK_PRIORITY_5);
    }
    /**
     * 处理异步后台任务6
     *
     * @param $idSuffix
     */
    public function actionProcessSix($idSuffix)
    {
        $this->processCore($idSuffix, Consts::TASK_PRIORITY_6);
    }
    /**
     * 处理异步后台任务7
     *
     * @param $idSuffix
     */
    public function actionProcessSeven($idSuffix)
    {
        $this->processCore($idSuffix, Consts::TASK_PRIORITY_7);
    }
    /**
     * 处理一小时前的异步任务
     */
    public function actionProcessOneHourBefore()
    {
        $tasks = TaskHelper::getTop100NeedProcessOneHourBeforeAsyncTask();
        foreach ($tasks as $task) {
            $task = Task::findOne($task['id']);
            TaskHelper::processTask($task);
        }
    }

    protected function processOneCore($priority = 1){
        //让后台Crontab错开查询时间,让对Task表的并发查询量下降.
        //提高查询Task的性能
        if (YII_ENV_PROD) {
            sleep(($priority - 1) * 5 + rand(0, 5));
        }

        echo (sprintf('Start Process Core')).PHP_EOL;

        $task_only_with_id = TaskHelper::getTopOneNeedProcessAsyncTask($priority);
        $task = Task::findOne($task_only_with_id['id']);

        if (!$task){
            echo ('==========No Task Need To Run==========').PHP_EOL;
            return;
        }

        $response = TaskHelper::processTask($task);
        if($response->code == TaskResponseData::CODE_ERROR){
            $task->status = Consts::TASK_STATUS_ERROR;
            $task->response_data = $response->message;
            $task->save();
        }
        echo (sprintf('Task [%s] Finished at %s. Message: %s', $task->key, DateHelper::getCurrentDateTime(), $response->message));
    }

    /***
     * 异步任务核心处理
     *
     * @param $idSuffix
     * @param $priority
     */
    protected function processCore($idSuffix, $priority)
    {
        //让后台Crontab错开查询时间,让对Task表的并发查询量下降.
        //提高查询Task的性能
        if (YII_ENV_PROD) {
            sleep(($priority - 1) * 5 + rand(0, 5));
        }

        $sliceArray = explode(',', $idSuffix);
        echo (sprintf('Start Process Core : sliceCount : %d, totalCount : %d', $sliceArray[0], $sliceArray[1]));
//        return;

        $tasks_array_only_with_id      = TaskHelper::getTop100NeedProcessAsyncTask($sliceArray[0], $sliceArray[1], $priority);

        if (count($tasks_array_only_with_id) == 0){
            echo PHP_EOL;
            echo ('==========No Task Need To Run==========');
            echo PHP_EOL;
            return;
        }

        foreach ($tasks_array_only_with_id as $task_only_with_id) {
            $task = Task::findOne($task_only_with_id['id']);

            echo PHP_EOL;
            echo ('=========='.$task->key.'==========');
            echo PHP_EOL;

            $response = TaskHelper::processTask($task);
            if($response->code == TaskResponseData::CODE_ERROR){
                $task->status = Consts::TASK_STATUS_ERROR;
                $task->response_data = $response->message;
                $task->save();
            }
            echo (sprintf('Task [%s] Finished at %s. Message: %s', $task->key, DateHelper::getCurrentDateTime(), $response->message));
        }
    }

    public function actionSyncEmployeeFromHr(){
        echo ('=========='.Yii::t('app', 'Sync Employee from HR').'==========');
        echo PHP_EOL;
        $result = (new TaskService())->createTask(Consts::TASK_TYPE_EMPLOYEE, 'hr', Consts::NO);
        echo $result->getMessage();
    }

    public function actionSyncEmployeePhoto(){
        echo ('=========='.Yii::t('app', 'Sync Employee Photo').'==========');
        echo PHP_EOL;
        $result = (new TaskService())->createTask(Consts::TASK_TYPE_EMPLOYEE_PHOTO, 'hr', Consts::NO);
        echo $result->getMessage();
    }

    public function actionSyncDepartmentFromHr(){
        echo ('=========='.Yii::t('app', 'Sync Department From HR').'==========');
        echo PHP_EOL;
        $result = (new TaskService())->createTask(Consts::TASK_TYPE_DEPARTMENT_FROM_HR, 'hr', Consts::NO);
        echo $result->getMessage();
    }

    public function actionSyncEmployeeDepartmentRelationFromHr(){
        echo ('=========='.Yii::t('app', 'Sync Employee Department Relation From HR').'==========');
        echo PHP_EOL;
        $result = (new TaskService())->createTask(Consts::TASK_TYPE_EMPLOYEE_DEPARTMENT, 'hr', Consts::NO);
        echo $result->getMessage();
    }

    public function actionSyncDepartmentToQywx(){
        echo ('=========='.Yii::t('app', 'Sync Department To Qywx').'==========');
        echo PHP_EOL;
        $result = (new TaskService())->createTask(Consts::TASK_TYPE_DEPARTMENT_TO_QYWX, 'qywx', Consts::NO);
        echo $result->getMessage();
    }

    public function actionSyncEmployeeToQywx(){
        echo ('=========='.Yii::t('app', 'Sync Employee To Qywx').'==========');
        echo PHP_EOL;
        $result = (new TaskService())->createTask(Consts::TASK_TYPE_EMPLOYEE_TO_QYWX, 'qywx', Consts::NO);
        echo $result->getMessage();
    }

    public function actionExecuteMdmTasks(){
        echo ('=========='.Yii::t('app', 'Execute Mdm Tasks').'==========');
        echo PHP_EOL;
        $result = (new TaskService())->createTask(Consts::TASK_TYPE_MDM_TASK, 'mdm', Consts::NO);
        echo $result->getMessage();
    }
}